<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<meta name="viewport" content="width=device-width, initial-scale=1.0">  
<title>Text Selection and Paste Listener</title>  
<style>  
    #editable {  
        border: 1px solid #ccc;  
        min-height: 100px;  
        padding: 10px;  
        width: 300px;  
    }  
</style>  
</head>  
<body>  
  
<div id="editable" contenteditable="true">  
    在这里输入文本...  
</div>  
  
<script>  
    const editable = document.getElementById('editable');  
document.addEventListener('selectionchange',  function() {  
        const selection = window.getSelection();  
        console.log('selection',selection)
        if (selection.rangeCount > 0) {  
    var range = selection.getRangeAt(0); // 获取第一个Range对象  
    console.log("range",range)
    console.log("startOffset:", range.startOffset);  
    console.log("endOffset:", range.endOffset);  
    console.log("Focus Node:", range.focusNode);  
    console.log("Focus Offset:", range.focusOffset);  
    console.log("Is Collapsed:", selection.isCollapsed);  
    console.log("Range Count:", selection.rangeCount);  
} else {  
    console.log("No selection is made.");  
}
        // 检查是否有选中的文本  
        if (selection.rangeCount > 0) {  
            const range = selection.getRangeAt(0);  
  
            // 检查选中的文本是否位于 editable 内  
            if (range.commonAncestorContainer.closest('#editable') === editable ) {  
                // 获取 editable 的文本内容  
                const text = editable.textContent;  
  
                // 计算选中区域的开始索引和结束索引  
                let startIndex = -1, endIndex = -1;  
  
                // 由于我们需要的是基于整个文本内容的索引，我们需要遍历 editable 的子节点  
                // 并找到包含选区起点的那个文本节点  
                let currentRange = range.cloneRange();  
                currentRange.setStart(editable .firstChild, 0);  
  
                // 遍历直到找到起点  
                while (currentRange.compareBoundaryPoints(Range.END_TO_START, range) < 0) {  
                    if (currentRange.endContainer.nodeType === Node.TEXT_NODE) {  
                        startIndex += currentRange.endContainer.textContent.length;  
                    }  
                    currentRange.setEndAfter(currentRange.endContainer);  
                }  
  
                // 如果起点是一个文本节点的一部分，则需要加上该文本节点中到起点的长度  
                if (range.startContainer.nodeType === Node.TEXT_NODE && range.startOffset > 0) {  
                    startIndex += range.startOffset;  
                }  
  
                // 类似地，计算结束索引  
                currentRange = range.cloneRange();  
                currentRange.setEnd(editable.lastChild, editable.lastChild.textContent.length);  
  
                while (currentRange.compareBoundaryPoints(Range.START_TO_END, range) > 0) {  
                    if (currentRange.startContainer.nodeType === Node.TEXT_NODE) {  
                        endIndex = startIndex + currentRange.startContainer.textContent.length;  
                    }  
                    currentRange.setStartBefore(currentRange.startContainer);  
                }  
  
                // 如果终点是一个文本节点的一部分，则调整结束索引  
                if (range.endContainer.nodeType === Node.TEXT_NODE && range.endOffset < range.endContainer.textContent.length) {  
                    endIndex = startIndex + range.endOffset;  
                } else {  
                    // 如果终点是文本节点的末尾，则endIndex应该是整个文本的长度  
                    endIndex = text.length;  
                }  
  
                console.log('Start Index:', startIndex);  
                console.log('End Index:', endIndex);  
            } else {   
            }  
        }  
    });  
  
    // 监听粘贴事件  
    editable.addEventListener('paste', function(event) {  
        const clipboardData = event.clipboardData || window.clipboardData;  
        const pastedData = clipboardData.getData('text');  
        console.log('Pasted text:', pastedData);  
  
        // 阻止默认粘贴行为（如果需要）  
        // event.preventDefault();  
  
        // 这里可以添加代码来修改粘贴的内容  
        // 注意：如果阻止了默认行为，你需要手动将文本插入到文档中  
    });  
  
    // 监听输入事件  
    editable.addEventListener('input', function() {  
        // 这里通常不直接获取插入的值或位置，因为input事件只告诉你内容变了  
        // 但你可以结合selectionchange事件来获取更多信息  
        console.log('Input event triggered');  
    });  
  
    // 注意：对于精确的插入位置和值，你可能需要更复杂的逻辑  
    // 比如，在paste事件中阻止默认行为，然后手动处理粘贴的文本  
</script>  
  
</body>  
</html>